#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "tag.h"

void tstack_top( tstack_t *ts, tag_t **pt)
{
  if ( ts->n )
    *pt = &ts->v[ts->n-1];
  else
    *pt = 0;
}

void tstack_push(tstack_t *ts, tag_t *t)
{
  if ( ts->n == ts->c )
  {
    ts->c *= 2;
    ts->v = (tag_t*)realloc(ts->v,sizeof(tag_t)*ts->c);
  }
  ts->v[ts->n++] = *t; //copy it onto the stack
}

bool tstack_pop(tstack_t *ts, tag_t *t)
{
  if ( ts->n > 0 )
  {
    *t = ts->v[--ts->n]; //copy from the stack
    return true;
  }
  else
  {
    return false;
  }
}

void tstack_create(tstack_t *ts)
{
	if ( !ts->init )
	{
		ts->c = 10;
		ts->v = (tag_t*)malloc(sizeof(tag_t)*ts->c);
    for ( int i = 0; i < ts->c; i++ )
      ts->v[i] = DEFAULT_TAG;
		ts->n = 0;
		ts->init = true;
	}
}

void tag_free(tag_t *t)
{
  str_free(&t->tok);
}

void tstack_free_tags(tstack_t *ts)
{
  tstack_clear(ts);
}

void tstack_free(tstack_t *ts)
{
  tstack_clear(ts);
  free(ts->v);
}

void tstack_clear(tstack_t *ts)
{
  for ( int i = 0; i < ts->n; i++ )
    tag_free(&ts->v[i]);
  ts->n=0;
}

void make_tok( str_t *dst, str_t *src )
{
  char *c = src->v;
  while ( *c == '>' || *c == '\n' 
      || *c == ' ' || *c == '\t' )
    c++;
  str_cpy( dst, c );
}

void make_tag( str_t* tok, tag_t *t)
{
  if ( tok->v[0] != '<' )
    return; //not valid tag

  char *stok;
  if ( tok->v[1] == '/' )
  {
    t->end = true;
    stok = tok->v+2;
  }
  else
  {
    t->end = false;
    stok = tok->v+1;
  }

  int c = 0;
  char * pch;
  char * brk = " \t";

  pch = strtok (stok,brk);
  while (pch != NULL)
  {
    if ( !c++ )
    {
      //process the name
      strcpy(t->name,pch);
    }
    else
    {
      //process attrs
      sscanf(pch,"%[^=]=%[^=]",
          t->attrs[t->nattrs].key,
          t->attrs[t->nattrs].val );
      t->nattrs++;
    }
    pch = strtok (NULL,brk);
  }

}


void tstack_invert(tstack_t *dst, tstack_t *src)
{
	tstack_create(dst);
	tag_t tag = DEFAULT_TAG;
	while( tstack_pop( src,&tag ) )
	{
		tstack_push(dst,&tag);
	}
}
